﻿#pragma once

#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>

#include "SourceCode/Renderer/Camera.h"
#include "SourceCode/Events/Event.h"

namespace Hazal
{
	class CEditorCamera : public CCamera
	{
	public:
		CEditorCamera() = default;

		CEditorCamera(float fFov, float aspectRatio, float fNearClip, float fFarClip);

	public:
		void OnUpdate(float fTimeSpan);

		void OnEvent(CEvent& event);

	public:
		inline float GetDistance() { return m_fDistance; }
		inline void SetDistance(float fDistance) { m_fDistance = fDistance; }

		inline void SetViewportSize(float fWidth, float fHeight) { m_fWidth = fWidth; m_fHeight = fHeight; UpdateProjection(); }

		inline const glm::mat4& GetViewMatrix() const { return m_matViewMatrix; }
		inline glm::mat4 GetViewProjection() const { return m_matProjection * m_matViewMatrix; }

	public:
		glm::vec3 GetUpDirection() const;
		glm::vec3 GetRightDirection() const;
		glm::vec3 GetForwardDirection() const;

		const glm::vec3 GetPosition() const { return m_vecPosition; }
		glm::quat GetOrientation() const;

		float GetPitch() const { return m_fPitch; }
		float GetYaw() const { return m_fYaw; }

	private:
		void UpdateProjection();
		void UpdateView();

		bool OnMouseScroll(CMouseScrolledEvent& event);

		/// 鼠标相关事件处理逻辑
		void MousePan(const glm::vec2& vecDelta);
		void MouseRotate(const glm::vec2& vecDelta);
		void MouseZoom(float vecDelta);

		glm::vec3 CalculatePosition() const;

		std::pair<float, float> PanSpeed() const;	/// 平移速率
		float RotationSpeed() const;				/// 旋转速率
		float ZoomSpeed() const;					/// 缩放速率


	private:
		///  透视投影矩阵相关参数
		float m_fFov = 30.0f, m_fAspectRatio = 1.778f, m_fNearClip = 0.1f, m_fFarClip = 1000.0f;

		/// 视窗大小
		float m_fWidth = 1280.0f, m_fHeight = 720.0f;

		glm::mat4 m_matViewMatrix = glm::mat4(1.0f);

		/// 相机位置
		glm::vec3 m_vecPosition = { 0.0f, 0.0f, 0.0f };
		glm::vec3 m_vecFocalPoint = { 0.0f, 0.0f, 0.0f };

		/// 鼠标初始位置
		glm::vec2 m_vecInitialMousePosition = { 0.0f, 0.0f };

		float m_fDistance = 10.0f;

		/// 俯仰角(X轴), 偏航角(Y轴)
		float m_fPitch = 0.0f, m_fYaw = 0.0f;
	};
}
